<template>
  <v-container>
    <h1 class="text-h4 mb-6">AI营养分析助手</h1>

    <v-row>
      <!-- 左侧：上传区域 -->
      <v-col cols="12" md="5">
        <v-card>
          <v-card-text>
            <v-file-input
                v-model="selectedFile"
                label="点击这里选择或拖拽食物图片"
                accept="image/*"
                variant="outlined"
                prepend-icon="mdi-camera"
                show-size
                @update:model-value="previewImage"
            ></v-file-input>

            <v-img
                v-if="imagePreviewUrl"
                :src="imagePreviewUrl"
                class="my-4"
                max-height="300"
                contain
            ></v-img>

            <v-select
                v-model="selectedMealType"
                :items="mealTypeOptions"
                label="这是哪一餐？"
                variant="outlined"
                class="mt-4"
            ></v-select>
          </v-card-text>
          <v-card-actions>
            <v-spacer></v-spacer>
            <v-btn
                color="primary"
                size="large"
                @click="handleAnalyze"
                :loading="isAnalyzing"
                :disabled="!selectedFile"
            >
              开始分析
            </v-btn>
          </v-card-actions>
        </v-card>
      </v-col>

      <!-- 右侧：结果展示区域 -->
      <v-col cols="12" md="7">
        <div v-if="isAnalyzing" class="text-center pa-10">
          <v-progress-circular indeterminate color="primary" size="64"></v-progress-circular>
          <p class="mt-4 text-grey">AI正在努力识别中，请稍候...</p>
        </div>
        <v-alert v-else-if="!analysisResult" type="info" variant="tonal">
          分析结果将在这里显示
        </v-alert>
        <v-card v-else variant="outlined">
          <v-card-title>分析结果</v-card-title>
          <v-list>
            <v-list-item>
              <v-list-item-title class="font-weight-bold">{{ analysisResult.recognizedFoodName }}</v-list-item-title>
              <v-list-item-subtitle>{{ analysisResult.estimatedWeightGrams }} 克 (估算)</v-list-item-subtitle>
            </v-list-item>
          </v-list>
          <v-divider></v-divider>
          <v-table density="compact">
            <thead>
            <tr><th class="text-left">营养成分</th><th class="text-right">含量</th></tr>
            </thead>
            <tbody>
            <tr><td>热量</td><td class="text-right">{{ analysisResult.calories }} 大卡</td></tr>
            <tr><td>蛋白质</td><td class="text-right">{{ analysisResult.proteinGrams }} 克</td></tr>
            <tr><td>碳水化合物</td><td class="text-right">{{ analysisResult.carbsGrams }} 克</td></tr>
            <tr><td>脂肪</td><td class="text-right">{{ analysisResult.fatGrams }} 克</td></tr>
            </tbody>
          </v-table>
        </v-card>
      </v-col>
    </v-row>
  </v-container>
</template>

<script setup>
import { ref } from 'vue';
import Request from '@/utils/Request';
import { useNotificationStore } from '@/stores/notification';

const notificationStore = useNotificationStore();

const selectedFile = ref(null);
const imagePreviewUrl = ref('');
const selectedMealType = ref(1); // 默认为午餐 (1)
const isAnalyzing = ref(false);
const analysisResult = ref(null);

const mealTypeOptions = [
  { title: '早餐', value: 0 },
  { title: '午餐', value: 1 },
  { title: '晚餐', value: 2 },
  { title: '加餐/零食', value: 3 },
];

const previewImage = (file) => {
  const targetFile = Array.isArray(file) ? file[0] : file;
  if (targetFile) {
    selectedFile.value = targetFile;
    const reader = new FileReader();
    reader.onload = (e) => {
      imagePreviewUrl.value = e.target.result;
    };
    reader.readAsDataURL(targetFile);
  } else {
    selectedFile.value = null;
    imagePreviewUrl.value = '';
  }
};


/**
 * 使用封装好的 Request.streamUpload 来处理AI分析
 */
const handleAnalyze = () => {
  if (!selectedFile.value) {
    notificationStore.warning('请先选择一张图片');
    return;
  }
  isAnalyzing.value = true;
  analysisResult.value = null;
  let accumulatedJson = ''; // 用于拼接AI返回的JSON片段

  const formData = new FormData();
  formData.append('Image', selectedFile.value);
  formData.append('MealType', selectedMealType.value);
  // 定义 onError 回调，以便在多个地方引用
  const onErrorCallback = (error) => {
    console.error("AI识餐失败:", error);
    notificationStore.error(error.message || '分析过程中发生未知错误');
    analysisResult.value = null;
    isAnalyzing.value = false;
  };
  Request.streamUpload('/api/nutrition/analyze-stream', formData, {
    /**
     * 每次从流中收到一个数据片段时被调用
     */
    onData: (jsonChunk) => {
      accumulatedJson += jsonChunk;
    },

    /**
     * 当数据流正常结束时被调用
     */
    onDone: () => {
      try {
        if (!accumulatedJson) {
          throw new Error("AI未能返回任何分析数据。");
        }

        const finalResult = JSON.parse(accumulatedJson);

        if (finalResult.error) throw new Error(finalResult.error);

        if (finalResult.recognizedFoodName?.includes("无法识别")) {
          notificationStore.warning("AI未能识别出图片中的食物，请换一张图片试试。");
          analysisResult.value = finalResult;
          isAnalyzing.value = false;
          return;
        }

        notificationStore.success('AI分析完成！正在为您保存记录...');
        analysisResult.value = finalResult;

        // 分析成功后，调用保存函数
        logMealEntry(finalResult);
      } catch (e) {
        // 如果在解析或处理最终数据时出错
        onErrorCallback(e);
      }
    },
    onError: onErrorCallback
  });
};

/**
 * 将分析结果发送到后端进行保存
 * @param {object} mealData 从AI获取到的完整营养数据
 */
const logMealEntry = async (mealData) => {
  try {
    const payload = { ...mealData, mealType: selectedMealType.value };
    const response = await Request.post('/nutrition/log-meal', payload);
    analysisResult.value = response.data; // 用后端返回的最终数据更新UI
    notificationStore.success('饮食记录已成功保存！');
  } catch (error) {
    console.error("保存饮食记录失败:", error);
    notificationStore.error(error.message || '保存记录时发生错误。');
  } finally {
    // 无论保存成功与否，分析流程都已结束
    isAnalyzing.value = false;
  }
};
</script>